home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Archive / Graphics / QuickDraw GX / GX->PostScript Sample / GXToPostScript / Imaging Engine / ShapePartsDrones.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  22.2 KB  |  841 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:            ShapePartsDrones.c
  3.  
  4.      Contains:    QuickDraw GX to PostScript conversion code.
  5.                          File contains Routines for the Imaging Engine Shape Parts Drones.
  6.  
  7.      Version:    Technology:    Quickdraw GX 1.1.x
  8.       
  9.      Copyright:    © 1991-1997 by Apple Computer, Inc., all rights reserved.
  10. */
  11.  
  12. #include "GXToPSBuildConfig.h"
  13. #include "GXToPostScript.h"
  14. #include "RDUtil.h"
  15. #include "PublicPostScriptIE.h"
  16. #include "private.h"
  17. #include "PSIEResources.h"
  18. #include <GXGraphics.h>
  19.  
  20. #ifdef resumeLabel
  21.     #undef resumeLabel
  22. #endif
  23. #define resumeLabel(exception)
  24.  
  25.  
  26.  
  27. //<FF>
  28. /************************************
  29.     StyleDrone:
  30.     
  31.     Convert the gx graphics style into PostScript
  32.     or output PostScript synonym on the style.
  33.     
  34.     hIEGlobals:            the Imaging Engine globals
  35.     theStyle:                The style to translate.
  36.     theShape:                The shape it came from.
  37.     makeDict:                true if client wants a style dictionary, false for immediate output
  38.     
  39. *************************************/
  40. OSErr _StyleDrone(TIEGlobalsHdl hIEGlobals, gxStyle theStyle)
  41.     {
  42.         OSErr                                status = noErr;
  43.         long                                nSyn, i;
  44.         gxTag                                psSynonym;
  45.         TIEGlobalsPtr                pGlobals;
  46.     
  47.         pGlobals = *hIEGlobals;
  48.         pGlobals->ieStateFlags |= eSimpleStyle;                // Initialize simple style to true, updated by style primitives.
  49.         
  50.         nSyn = GXGetStyleTags(theStyle, gxPostScriptTag, 1, gxSelectToEnd, nil);
  51.     
  52.         if (nSyn > 0) {
  53.         
  54.             nrequire(status = RDFlushBuffer(pGlobals->rdMap), failed_Style);        /* OutputTag calls buffer data message dirctly */
  55.             nrequire(status = EndProcSetDict(pGlobals->pRDParams), failed_Style);
  56.  
  57.             for (i = 1; i <= nSyn; ++i) {
  58.             
  59.                 GXGetStyleTags(theStyle, gxPostScriptTag, i, 1, &psSynonym);
  60.                 nrequire(status = OutputTag(hIEGlobals, psSynonym), failed_Style);
  61.                 
  62.             }//end for
  63.             
  64.             pGlobals = *hIEGlobals;
  65.             pGlobals->ieStateFlags |= (eStyleOutOfDate | eFontOutOfDate);
  66.  
  67.             nrequire(status = BeginProcSetDict(pGlobals->pRDParams), failed_Style);
  68.         
  69.         } else {
  70.     
  71.             status = MiscStylePrimitive(hIEGlobals, theStyle);
  72.             nrequire(status, failed_Style);
  73.                                 
  74.             status = FrameStylePrimitive(hIEGlobals, theStyle);
  75.             nrequire(status, failed_Style);
  76.  
  77.             (*hIEGlobals)->ieStateFlags &= ~eStyleOutOfDate;
  78.             
  79.         }//end if
  80.     
  81.  
  82. failed_Style:
  83.     return(status);
  84.         
  85.     }//StyleDrone
  86.     
  87.     
  88.     
  89.  
  90. //<FF>
  91. /************************************
  92.     TransformDrone:
  93.     
  94.     Convert the gx graphics transform into PostScript
  95.     or use PostScript synonym on the transform.
  96.     
  97.     hIEGlobals:            the Imaging Engine globals
  98.     theTransform:        The transform to translate.
  99.     
  100. *************************************/
  101. OSErr _TransformDrone(TIEGlobalsHdl hIEGlobals, gxTransform theTransform)
  102.     {
  103.         OSErr                            status = noErr;
  104.         gxMapping                    theMapping;
  105.         gxShape                        theClip;
  106.         TRDParams*                pRDParams;
  107.         TIEGlobalsPtr            pGlobals;
  108.         TGstate*                    pCurrGstate;
  109.         gxTransform                currTransform;
  110.         gxShapeType                clipType;
  111.         gxShapeFill                clipFill;
  112.         Boolean                        clippedIt = false;
  113.         long                            nSyn, i;
  114.         gxTag                            psSynonym;
  115.         long                            clipPoints;
  116.         
  117.         pGlobals = *hIEGlobals;
  118.         pRDParams = pGlobals->pRDParams;    
  119.     
  120.         /** Update current graphics state with new transform **/
  121.  
  122.         pCurrGstate = &(pGlobals->gStateNest[pGlobals->gStateDepth]);
  123.         currTransform = pCurrGstate->theTransform;
  124.         pCurrGstate->theTransform = GXCloneTransform(theTransform);
  125.         GXDisposeTransform(currTransform);
  126.             
  127.         
  128.         /**** Output the transform - either from synonym or actual object data *****/
  129.  
  130.         nSyn = GXGetTransformTags(theTransform, gxPostScriptTag, 1, gxSelectToEnd, nil);
  131.         
  132.         if (nSyn > 0) {
  133.  
  134.             nrequire(status = EndProcSetDict(pRDParams), failed_Transform);
  135.             nrequire(status = RDFlushBuffer(pRDParams->rdMap), failed_Transform);        /* OutputTag calls buffer data message dirctly */
  136.  
  137.             for (i = 1; i <= nSyn; ++i) {
  138.             
  139.                 GXGetTransformTags(theTransform, gxPostScriptTag, i, 1, &psSynonym);
  140.                 nrequire(status = OutputTag(hIEGlobals, psSynonym), failed_Transform);
  141.                 
  142.             }//end for
  143.             
  144.             (*hIEGlobals)->ieStateFlags |= eTransformOutOfDate;
  145.     
  146.             nrequire(status = BeginProcSetDict(pRDParams), failed_Transform);
  147.         
  148.         } else {
  149.         
  150.             GXGetTransformMapping(theTransform, &theMapping);
  151.             
  152.             theClip = GXGetTransformClip(theTransform);
  153.             
  154.             require_action(theClip, failed_GetClip, status = GXGetGraphicsError(nil););
  155.             
  156.             clipType = GXGetShapeType(theClip);
  157.             clipFill = GXGetShapeFill(theClip);
  158.             
  159.             status = PSCountShapePoints(theClip, 0, &clipPoints);
  160.             nrequire(status, failed_CountClipPoints);
  161.             
  162.             pGlobals = *hIEGlobals;            // Deref handle in case mem moved.
  163.         
  164.             /** Update current graphics state with points available after clip **/
  165.  
  166.             pCurrGstate = &(pGlobals->gStateNest[pGlobals->gStateDepth]);
  167.             pCurrGstate->pointsAvail -= clipPoints;
  168.             
  169.             /** Concatonate CTM with the mapping **/
  170.                         
  171.             if (!TestMappingIdentity(&theMapping)) {
  172.             
  173.                 status = MappingPrimitive(hIEGlobals, &theMapping);
  174.                 nrequire(status, failed_Output);
  175.                 
  176.             }//end if
  177.             
  178.             
  179.             /***** Now do set the clip *****/
  180.             
  181.             /*****
  182.                 Don't do anything for wide-open clips:
  183.                 This means full shape non-inverse filled
  184.             *****/
  185.             if ( (clipType != gxFullType) || (clipFill == gxInverseFill) || (clipFill == gxInverseWindingFill) ) {    
  186.             
  187.                 status = _GeometryDrone(hIEGlobals, theClip, eClipGeometry, nil, 0);
  188.                 nrequire(status, failed_Geometry);
  189.             
  190.                 if ( (clipType == gxRectangleType) ) {            // See if we can use RectClip
  191.                                 
  192.                     if ((clipFill == gxEvenOddFill) || (clipFill == gxWindingFill)) {
  193.                     
  194.                         pRDParams->resIndex = kRectClip;
  195.                         clippedIt = true;
  196.                         
  197.                     }    else {
  198.                     
  199.                         pRDParams->resIndex = kRectPath;
  200.                         
  201.                     }//end if
  202.                     
  203.                     status = RDResPrintf(pRDParams);
  204.                     nrequire(status, failed_Output);
  205.                                 
  206.                 }//end if
  207.     
  208.                 /** If it isn't already the clip (cause of rectclip or fullshapes) then make the path the clip **/
  209.             
  210.                 if (!clippedIt) {
  211.                 
  212.                     status = DoFillKey(pRDParams, clipFill);
  213.                     nrequire(status, failed_Output);
  214.                     
  215.                     pRDParams->resIndex = kQD2Clip;
  216.                     status = RDResPrintf(pRDParams);
  217.                     nrequire(status, failed_Output);
  218.                     
  219.                 }//end if
  220.                 
  221.             }//end if
  222.                                                     
  223.             (*hIEGlobals)->ieStateFlags &= ~eTransformOutOfDate;
  224.  
  225. failed_Geometry:        
  226. failed_Output:
  227.  
  228.             GXDisposeShape(theClip);
  229.             
  230.  
  231.         }//end if
  232.                 
  233. failed_CountClipPoints:
  234. failed_GetClip:
  235.  
  236. failed_Transform:
  237.  
  238.         return(status);
  239.         
  240.     }//TransformDrone
  241.     
  242.  
  243.  
  244. //<FF>
  245. /************************************
  246.     FillShapeDrone:
  247.     
  248.     Convert the gx graphics style into PostScript
  249.     
  250.     hIEGlobals:            the Imaging Engine globals
  251.     theStyle:                The style to translate.
  252.     theShape:                The shape it came from.
  253.     parents:                pointer to list of parent transforms.  (nil means ignore)
  254.     depth:                    number of parents.                                         (pass zero if nil passed for above)
  255.     
  256. *************************************/
  257. OSErr    _FillShapeDrone(TIEGlobalsHdl hIEGlobals, gxShape theShape, gxTransform *parents, long depth)
  258.     {
  259.         OSErr                        status;
  260.         gxShapeType            shType;
  261.         gxShapeFill            theFill;
  262.         TRDParams                *rdParams;
  263.         TIEGlobalsPtr        pIEGlobals;
  264.         Boolean                    paintedIt = false;
  265.         
  266.         shType = GXGetShapeType(theShape);
  267.         theFill = GXGetShapeFill(theShape);
  268.         
  269.         pIEGlobals = *hIEGlobals;
  270.         rdParams = pIEGlobals->pRDParams;
  271.  
  272.         /**************
  273.             If the shape's fill is one of the standard PostScript fills
  274.             then simpleStyle can be true.  This allows us to call PostScript
  275.             Fill operators directly rathern than going through QD2Fill
  276.             when doing immediate geometry output.  Thus inverse-fill
  277.             since inverse-fill is not a PostScript fill so we turn
  278.             it off it was set by the StyleDrone.
  279.         ***************/
  280.         if (theFill == gxInverseFill)
  281.             pIEGlobals->ieStateFlags &= ~eSimpleStyle;
  282.                 
  283.         
  284.         nrequire(status = _GeometryDrone(hIEGlobals, theShape, eNoGeomOptions, parents, depth), failed_Geometry);
  285.  
  286.         pIEGlobals = *hIEGlobals;                    // get it again, in case it moved.
  287.         
  288.  
  289.         /*******************************************
  290.             Rectangles can paint themselves sometimes.
  291.                 Do the right thing with the 2 rect points that the
  292.                 rectangle primitive left on the stack either way
  293.         
  294.             Text, layouts, glyhs, and bitmaps always paint themselves,
  295.             Check for these cases and don't do qd2fill.
  296.             
  297.         *********************************************/
  298.  
  299.         if ( (shType == gxRectangleType) ) {            // See if we can paint the rectangle.
  300.         
  301.             if (pIEGlobals->ieStateFlags & eSimpleStyle) {
  302.         
  303.                 if ((theFill == gxClosedFrameFill) || (theFill == gxFrameFill))
  304.                     rdParams->resIndex = kRectStroke;
  305.                 else if ((theFill == gxEvenOddFill) || (theFill == gxWindingFill))
  306.                     rdParams->resIndex = kRectFill;
  307.                 
  308.                 status = RDResPrintf(rdParams);
  309.                 nrequire(status, failed_Output);
  310.                 
  311.                 paintedIt = true;
  312.                 
  313.             } else {
  314.             
  315.                 rdParams->resIndex = kRectPath;
  316.                 status = RDResPrintf(rdParams);
  317.                 nrequire(status, failed_Output);
  318.                 
  319.             }//end if
  320.             
  321.         } else if ((shType == gxTextType) || (shType == gxGlyphType) || (shType == gxBitmapType) ||
  322.                                 (shType == gxLayoutType) || (shType == gxEmptyType) ) {
  323.  
  324.             paintedIt = true;            
  325.         
  326.         }//end if
  327.  
  328.         /** See if we can paint it with a standard PostScript operator **/
  329.         
  330.         if (!paintedIt && ((*hIEGlobals)->ieStateFlags & eSimpleStyle) ) {
  331.         
  332.             switch (theFill) {
  333.             
  334.                 case gxEvenOddFill:
  335.                     rdParams->resIndex = kEofill;
  336.                     paintedIt = true;
  337.                     nrequire(status = RDResPrintf(rdParams), failed_Output);
  338.                     break;
  339.                     
  340.                 case gxWindingFill:
  341.                     rdParams->resIndex = kFill;
  342.                     paintedIt = true;
  343.                     nrequire(status = RDResPrintf(rdParams), failed_Output);
  344.                     break;
  345.                     
  346.                 case gxFrameFill:
  347.                 case gxClosedFrameFill:
  348.                     rdParams->resIndex = kStroke;
  349.                     paintedIt = true;
  350.                     nrequire(status = RDResPrintf(rdParams), failed_Output);
  351.                     break;
  352.                     
  353.                 default:
  354.                     break;
  355.             
  356.             }//end switch        
  357.         
  358.         }//end if
  359.  
  360.         /** If it still hasn't been painted, paint it with QD2Fill **/
  361.         
  362.         if (!paintedIt ) {
  363.                         
  364.             nrequire(status = DoFillKey(rdParams, theFill), failed_Output);
  365.             
  366.             rdParams->resIndex = kQD2Fill;
  367.             nrequire(status = RDResPrintf(rdParams), failed_Output);
  368.                                         
  369.         }//end if
  370.     
  371.         
  372.         
  373. failed_Output:
  374. failed_Geometry:
  375.  
  376.         return(status);
  377.         
  378.     }//FillShapeDrone
  379.  
  380.  
  381.  
  382.  
  383. //<FF>
  384. /**************************************
  385.     GeometryDrone:
  386.     
  387.     This routine dispatches to the appropriate
  388.     primitive drone based upon the shape type.
  389.     It is also responsible for the encapsulation
  390.     of a geometry in a procedure definition.  See
  391.     ERS for more information.
  392.     
  393.     hIEGlobals:            The imaging engine globals.
  394.     theShape:                The shape to translate.
  395.     geomOptions:        the options for the geometry drone. (controls procedure definition)
  396.     parents:                pointer to the list of parent transforms (nil means no parents);
  397.     depth:                    number of parents.
  398.     
  399. ****************************************/
  400. OSErr    _GeometryDrone(TIEGlobalsHdl hIEGlobals, gxShape theShape, TgeometryOptions geomOptions, gxTransform *parents, long depth)
  401.     {
  402.         OSErr                status;
  403.         TRDParams*    pRDParams;
  404.         gxShapeType    shType;
  405.         gxShapeFill    shFill;
  406.         Boolean            rasterizeText = false;
  407.         
  408.         shType = GXGetShapeType(theShape);
  409.         shFill = GXGetShapeFill(theShape);
  410.         
  411.         pRDParams = (*hIEGlobals)->pRDParams;
  412.         
  413.         /*******
  414.             If it is a text or glyph shape, then resolve the fonts
  415.         *******/        
  416.         if ((shType == gxTextType) || (shType == gxGlyphType) || (shType == gxLayoutType)) {
  417.         
  418.             status = RDFlushBuffer((*hIEGlobals)->rdMap);            // Font handler can send messages so flush buffer.
  419.             nrequire(status, failed_Flush);
  420.             
  421.             status = FontHandlerResolveShapeFonts((*hIEGlobals)->fhContext, theShape);
  422.             if (status == no_outline_font_found) {
  423.                 status = noErr;
  424.                 rasterizeText = true;
  425.             }//end if
  426.             nrequire(status, failed_Fonts);
  427.             
  428.             /** If the font handler told us to rasterize the text, do it.  **/
  429.             
  430.             if (rasterizeText) {
  431.             
  432.                 status = PSRasterizeShape(hIEGlobals, theShape, parents, depth);
  433.                 nrequire(status, failed_RasterizeShape);
  434.                 
  435.             }//end if
  436.  
  437.             shType = GXGetShapeType(theShape);            // Resolving fonts may have changed text to glyph
  438.             
  439.         }//end if
  440.         
  441.         
  442.         /** Resolve inverse winding number fill **/
  443.         
  444.         if (shFill == gxInverseWindingFill) {
  445.         
  446.             GXSimplifyShape(theShape);
  447.             shType = GXGetShapeType(theShape);
  448.             shFill = GXGetShapeFill(theShape);
  449.         
  450.         }//end if
  451.         
  452.                         
  453.         /********************
  454.             If we are creating a proc for the geometry,
  455.             Begin the proc definition (the bitmap primitive
  456.             will handle this itself, however)
  457.         **********************/
  458.         if ( (geomOptions & eMakeProcedure) && (shType != gxBitmapType) ) {
  459.         
  460.             status = DoBeginProcedure(hIEGlobals);
  461.             nrequire(status, failed_Proc);
  462.         
  463.         }//end if
  464.         
  465.         
  466.         /*** Call the correct shape primitive ***/
  467.         
  468.         switch (shType) {
  469.         
  470.             case gxEmptyType:
  471.                 status = EmptyShapePrimitive(hIEGlobals, theShape, geomOptions);
  472.                 break;
  473.             
  474.             case gxFullType:
  475.                 status = FullShapePrimitive(hIEGlobals, theShape, geomOptions);
  476.                 break;
  477.                 
  478.             case gxRectangleType:
  479.                 status = RectanglePrimitive(hIEGlobals, theShape, geomOptions);
  480.                 break;
  481.                 
  482.             case gxLineType:
  483.                 status = LinePrimitive(hIEGlobals, theShape, geomOptions);
  484.                 break;
  485.                 
  486.             case gxPointType:
  487.                 status = PointPrimitive(hIEGlobals, theShape, geomOptions);
  488.                 break;
  489.             
  490.             case gxPolygonType:
  491.                 status = PolygonsPrimitive(hIEGlobals, theShape, geomOptions);
  492.                 break;
  493.                 
  494.             case gxTextType:
  495.                 status = TextPrimitive(hIEGlobals, theShape, geomOptions);
  496.                 break;
  497.             
  498.             case gxGlyphType:
  499.                 status = GlyphPrimitive(hIEGlobals, theShape, geomOptions);
  500.                 break;
  501.                 
  502.             case gxPathType:
  503.                 if (GXGetShapeTags(theShape, gxCubicSynonymTag, 1, 1, nil))
  504.                     status = CubicPrimitive(hIEGlobals, theShape, geomOptions);
  505.                 else
  506.                     status = PathsPrimitive(hIEGlobals, theShape, geomOptions);
  507.                 break;
  508.                 
  509.             case gxCurveType:
  510.                 status = CurvePrimitive(hIEGlobals, theShape, geomOptions);
  511.                 break;
  512.                 
  513.             case gxBitmapType:
  514.                 status = BitmapPrimitive(hIEGlobals, theShape, geomOptions);
  515.                 break;
  516.                         
  517. #if DEBUGLEVEL > 1
  518.             default:
  519.                 status = -999;
  520.                 dprintf(notrace, "Shape type %d not yet implemented in PostScript", (long)shType);
  521. #endif
  522.  
  523.         }//end switch
  524.     
  525.         nrequire(status, failed_Primitive);
  526.  
  527.         /********************
  528.             If we are creating a proc for the geometry,
  529.             End the proc definition (the bitmap primitive
  530.             will handle this itself, however)
  531.             
  532.         **********************/
  533.         if ( (geomOptions & eMakeProcedure) && (shType != gxBitmapType) ) {
  534.         
  535.             status = DoEndProcedure(hIEGlobals);
  536.             nrequire(status, failed_Proc);
  537.         
  538.         }//end if
  539.     
  540. failed_Primitive:
  541. failed_Proc:
  542. failed_RasterizeShape:
  543. failed_Fonts:
  544. failed_Flush:
  545.  
  546.         return(status);
  547.         
  548.     }//GeometryDrone
  549.  
  550.  
  551. //<FF>
  552. /***********
  553.  
  554.     routine: DoTransformHiearchy:
  555.     
  556.         Routine makes sure that the current nested graphics
  557.         state on the PostScript device matches the transform
  558.         hiearchy of the current shape.
  559.     
  560.         hIEGLobals:                imaging engine global state.
  561.         parents:                    Array of parent transforms of the current shape.
  562.         depth:                        Length of this array.
  563.         theShape:                    Current shape to be drawn.
  564.  
  565.  
  566.     Before doing anything: Deal with any perspective in the hiearchy.  
  567.         Then:
  568.  
  569.     Compare PostScript device's state to the parent transform list:
  570.     Compare the parent transforms to graphics state transforms
  571.     up to n.  (The n'th in the nest is the transform of the last
  572.     shape drawn.)
  573.     
  574.     
  575.     1.    if the current printer state depth is greater than new depth (plus 1 because of shape)
  576.                 grestore back to new depth.
  577.     2.    Compare transforms in new list to printer state.
  578.                 grestore back behind first one that is different.
  579.     3.    output any transforms that are in the new list to 
  580.                 update the printer state.
  581.     
  582. ************/        
  583. OSErr    _DoTransformHiearchy(TIEGlobalsHdl hIEGlobals, gxTransform *parents, long depth, gxShape theShape)
  584.     {
  585.         OSErr                                status = noErr;
  586.         long                                i, j, currDepth, newDepth;
  587.         TIEGlobalsPtr                pGlobals;
  588.         gxTransform                    shapesTransform, *pTransform;
  589.         TGstate*                        pGstate;
  590.                 
  591.         shapesTransform = GXGetShapeTransform(theShape);
  592.     
  593.         pGlobals = *hIEGlobals;                                        // dereference globals.
  594.  
  595.         /** Step 1 **/
  596.         
  597.         currDepth = pGlobals->gStateDepth + 1;        // gStateDepth is a zero based field so add one.
  598.         newDepth = depth + 1;                                            // Include shape's transform in new depth.
  599.         
  600.         // Make sure new depth is >= printer's depth.
  601.         
  602.         for (i = newDepth; i < currDepth; i++) {
  603.                         
  604.             status = _DoGrestore(hIEGlobals, false);
  605.             nrequire(status, failed_DoGrestore);
  606.             
  607.         }//end for
  608.         
  609.         pGlobals = *hIEGlobals;                                        // dereference globals.
  610.         currDepth = pGlobals->gStateDepth + 1;        // Get new depth after grestores, gStateDepth is a zero based field so add one.
  611.         
  612.         /** Step 2 **/
  613.         
  614.         pGstate = &(pGlobals->gStateNest[0]);    
  615.         pTransform = &(parents[0]);
  616.         for (i = 0; i < currDepth; ++i) {
  617.             
  618.             if (i == (newDepth-1))                                    // Skanky way to pretend shape's transform is in array.
  619.                 pTransform = &shapesTransform;
  620.                         
  621.             /** Break out of the loop when shape's transform doesn't match state's transform **/
  622.  
  623.             if (pGstate->theTransform != *pTransform)
  624.                 if (!PSEqualTransform(pGstate->theTransform, *pTransform))
  625.                     break;
  626.             
  627.             ++pGstate;
  628.             ++pTransform;
  629.         
  630.         }//end for
  631.                         
  632.         /** Grestore all transforms from i on **/
  633.         for (j = i; j < currDepth; ++j)
  634.             nrequire(status = _DoGrestore(hIEGlobals, false), failed_DoGrestore);
  635.  
  636.         /** Step 3 **/
  637.         
  638.         pGlobals = *hIEGlobals;
  639.         pTransform = &(parents[i]);
  640.         for (j = i; j < newDepth; ++j) {
  641.         
  642.             if ((j + 1) == newDepth )
  643.                 pTransform = &shapesTransform;            // Skanky way to pretend shape's transform is in array.
  644.  
  645.             status = _DoGsave(hIEGlobals, false);
  646.             nrequire(status, failed_DoGsave);
  647.                         
  648.             status = _TransformDrone(hIEGlobals, *pTransform);
  649.             nrequire(status, failed_Transform);
  650.             
  651.             #if DEBUGLEVEL > 1
  652.             
  653.                 pGlobals = *hIEGlobals;
  654.                 {
  655.                     unsigned char        pointsLeft[] = "%- points left: ";
  656.                     TRDParams*        rdParams = pGlobals->pRDParams;
  657.                     nrequire(status = PSIEBufferData(hIEGlobals, pointsLeft, 16, 0), failed_Transform);
  658.                     
  659.                     pGlobals = *hIEGlobals;
  660.                     
  661.                     rdParams->resIndex = kDoInt;
  662.                     nrequire(status = RDResPrintf(rdParams, pGlobals->gStateNest[pGlobals->gStateDepth].pointsAvail), failed_Transform);
  663.                 
  664.                 }
  665.             
  666.             #endif
  667.             
  668.             ++pTransform;
  669.         
  670.         }//end for
  671.  
  672.  
  673. failed_Transform:
  674. failed_DoGsave:
  675. failed_DoGrestore:
  676.  
  677.         return(status);
  678.  
  679.     }//DoTransformHiearchy
  680.  
  681.  
  682.  
  683.  
  684. //<FF>
  685. /*******************************************************
  686.     PostScriptSynonymDrone:
  687.     
  688.     Routine dumps the PostScript synonyms associated with a shape
  689.     
  690.     hIEGlobals:        the globals.
  691.     theShape:            the shape with the synonym.
  692.     nSyn:                    Number of PostScript synonyms.
  693.  
  694. *********************************************************/
  695. OSErr _PostScriptSynonymDrone(TIEGlobalsHdl hIEGlobals, gxShape theShape, long nSyn)
  696.     {
  697.         OSErr                                status;
  698.         long                                i, synSize;
  699.         gxTag                                psSynonym, controlTag;
  700.         gxPostControl                *postControlData;
  701.         long                                buffFlags;
  702.         TRDParams                        *rdParams;
  703.         long                                stateFlags;
  704.         gxPoint                            normalTangent = {ff(1), ff(0)};
  705.  
  706.         buffFlags = gxNoBufferOptions;
  707.         rdParams = (*hIEGlobals)->pRDParams;
  708.         
  709.         /** Get the control information, if it is there otherwise use defaults **/
  710.         
  711.         if (GXGetShapeTags(theShape, gxPostControlTag, 1, 1, &controlTag)) {
  712.         
  713.             GXLockTag(controlTag);
  714.             
  715.             postControlData = (gxPostControl*)((char*)GXGetTagStructure(controlTag, &synSize) - tagStructureBugOffset);
  716.             stateFlags = postControlData->flags;
  717.             
  718.             /** Do a save around synonym unless app said not to or in middle of multi-shape synonym. **/
  719.             
  720.             if (!(stateFlags & gxNoSave) ) {
  721.             
  722.                 rdParams->resIndex = kDoSave;
  723.                 nrequire_action(status = RDResPrintf(rdParams), failed_Output, GXUnlockTag(controlTag););
  724.                         
  725.                 /* make sure  continuation ignored if noSave isn't set */
  726.                 #if DEBUGLEVEL > 0
  727.                     if (stateFlags & gxPSContinueNext)
  728.                         dprintf(notrace, "gxPSContinueNext not allowed unless gxNoSave is set");
  729.                 #endif
  730.                 
  731.                 stateFlags &= ~(long)gxPSContinueNext;
  732.             
  733.             }//end if
  734.             
  735.             /* Note, this could be simply an Else of the above clause, too scared to change it 1.1.2 */
  736.             
  737.             if (stateFlags & gxNoSave) {    // Application is being evil, they don't want a save, so protect our state
  738.             
  739.                 /****
  740.                     This will force updating of graphics state (in context of transform nest) next 
  741.                         real gx graphics shape
  742.                 ****/
  743.                 (*hIEGlobals)->ieStateFlags |= eInitializeGstate;
  744.                 
  745.                 #ifndef GXTOPOSTSCRIPTLIBRARY
  746.                     /* This is for evil apps that use PostScript piccomments to change color (Informed Mgr) */
  747.                     if ((*hIEGlobals)->compatFlags.flags1 & kMaintainColorAcrossRestores)
  748.                         (*hIEGlobals)->ieStateFlags &= ~eColorOutOfDate;
  749.                 #endif
  750.                 
  751.             }//end if
  752.             
  753.             
  754.             GXUnlockTag(controlTag);
  755.             
  756.         } else {
  757.         
  758.             #if DEBUGLEVEL > 1
  759.             dprintf(trace, "PS Shape had no control tag");
  760.             #endif
  761.             
  762.             postControlData = nil;
  763.             stateFlags = 0;
  764.             
  765.             /** If no control synonym do a save/restore around postscript **/
  766.             
  767.             rdParams->resIndex = kDoSave;
  768.             nrequire(status = RDResPrintf(rdParams), failed_Output);
  769.  
  770.         }//end if
  771.         
  772.         /* If we are not already in the midst of a continuing synonym set up for synonym */
  773.         
  774.         if ( !( (*hIEGlobals)->ieStateFlags & ePSContinueNext ) ) {
  775.         
  776.             /* first, remove our dictionary from dict stack */        
  777.     
  778.             nrequire(status = EndProcSetDict(rdParams), failed_Output);
  779.             
  780.         }//end if
  781.         
  782.         
  783.         /* If this shape has will be followed by more for continuation, set our flag to indicate so */
  784.         
  785.         if ( stateFlags & gxPSContinueNext )
  786.             (*hIEGlobals)->ieStateFlags |= ePSContinueNext;
  787.         else
  788.             (*hIEGlobals)->ieStateFlags &= ~ePSContinueNext;
  789.         
  790.         
  791.         /** Output all of the PostScript data **/
  792.  
  793.         nrequire(status = RDFlushBuffer(rdParams->rdMap), failed_Flush);        /* OutputTag calls buffer data message dirctly */
  794.         
  795.         for (i = 1; i <= nSyn; ++i) {
  796.         
  797.             GXGetShapeTags(theShape, gxPostScriptTag, i, 1, &psSynonym);
  798.             nrequire(status = OutputTag(hIEGlobals, psSynonym), failed_Output);
  799.             
  800.         }//end for
  801.  
  802.  
  803.         /* Now, put our dictionary back on dict stack if we are not in midst of continuing synonym */        
  804.  
  805.         if ( !( (*hIEGlobals)->ieStateFlags & ePSContinueNext ) ) {
  806.  
  807.             nrequire(status = BeginProcSetDict(rdParams), failed_Output);
  808.             
  809.         }//end if
  810.         
  811.  
  812.         /** Finish a save/restore around synonym unless app said not to. **/
  813.         
  814.         if (!(stateFlags & gxNoSave)) {
  815.         
  816.             rdParams->resIndex = kDoRestore;
  817.             nrequire(status = RDResPrintf(rdParams), failed_Output);
  818.         
  819.         }//end if
  820.  
  821.         
  822.         /* If not in the midst of continuing ps synonym, output the trailer for synonyms */
  823.         
  824.         if ( !( (*hIEGlobals)->ieStateFlags & ePSContinueNext ) ) {
  825.  
  826.             rdParams->resIndex = kEndPSSyn;
  827.             nrequire(status = RDResPrintf(rdParams, nSyn, stateFlags), failed_Output);
  828.             
  829.         }//end if
  830.                 
  831.         status = GXGetGraphicsError(nil);
  832.         ncheck(status);
  833.         
  834. failed_Fonts:
  835. failed_Flush:
  836. failed_Output:
  837.  
  838.         return(status);
  839.     
  840.     }//PostScriptSynonymDrone
  841.